package hyl.base.flow.express;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * 解析字符串后形成的节点结构
 */
public class DependNode {

	private LinkedList<DependNode> childs = new LinkedList<>();// 子节点== or运算和and运算
	private DependNode _parent = null;// 父节点 and 运算
	//当前节点要么是内容,要么就是()括号
	public  DependNode _include = null; // 包含节点,非常重要的设计,解决了() 的问题
	private StringBuilder _content= null;// 有内容时 存放比较式 左边是字段 中间是符号,右边是char 或者chararray

	//解析出来的内容
	private StringBuilder field = new StringBuilder();// 左边是字段
	private SymbolType symbol;// 中间是符号
	private Character var='2';// 右边是char 值
	private StringBuilder var2;
	private boolean iserror = false;

	private DependNode() {

	}

	/**
	 * 判断该节点解析过程是否出错
	 */
	public boolean isError() {
		return iserror;
	}

	/**
	 * 实例化一个节点
	 */
	public static DependNode getInstance() {
		DependNode nd = new DependNode();
		return nd;
	}

	/**
	 * 实例化一个节点 挂载在parent下方
	 */
	public static DependNode getInsFromParent(DependNode parent) {
		DependNode nd = new DependNode();
		if (parent == null)
			return nd;
		parent.rpush(nd);
		nd._parent = parent;
		return nd;
	}

	/**
	 * 实例化一个表达式 () 节点 挂载在parent下方
	 */
	public static DependNode getInsExpFromParent(DependNode parent) {

		if (parent == null)
			return null;
		parent._include = new DependNode();
		return parent._include;
	}

	/**
	 * 获取子节点的数量
	 */
	public long len() {
		return childs.size();
	}

	/**
	 * 获取遍历子节点的接口
	 */
	public Iterator<DependNode> iterator() {
		return childs.iterator();
	}

	/**
	 * 获取节点 以节点位置
	 */
	public DependNode getNode(int index) {
		return childs.get(index);
	}

	/**
	 * 追加节点
	 */
	public void rpush(DependNode node) {
		childs.addLast(node);
	}

	/**
	 * 提取节点 栈方式 ,不取出
	 */
	public DependNode lpeek() {
		return childs.peekFirst();
	}

	/**
	 * 提取节点 栈方式 ,取出
	 */
	public DependNode lpoll() {
		return childs.pollFirst();
	}

	/**
	 * 提取节点 堆方式 ,取出
	 */
	public DependNode rpoll() {
		return childs.pollLast();
	}

	/**
	 * 提取节点 堆方式 ,不取出
	 */
	public DependNode rpeek() {
		return childs.peekLast();
	}

	/**
	 * 获取 比较符 左边的字段
	 */
	public String getField() {
		return field.toString();
	}

	/**
	 * 获取 比较符
	 */
	public SymbolType getSymbol() {
		return symbol;
	}

	/**
	 * 获取 比较符 右边的字符
	 */
	public char getVar() {
		return var;
	}

	/**
	 * 获取 in 右边的字符串
	 */
	public String getInVar() {
		return var2.toString();
	}

	/** 求每个算式的逻辑结果 */
	public boolean judge(char c) {
		if (symbol == null) {
				return (var == c);
		} else {
			switch (symbol) {
			case In:
			
				return (var2.toString().indexOf(c) >= 0);
			case Equal:
				return (var == c);
			case Unequal:
				return (var != c);
			case GT:
				return (c > var);
			case LT:
				return (c < var);
			case GTOrEqual:
				return (c >= var);
			case LTOrEqual:
				return (c <= var);
			default:
				return true;
			}
		}
	}

	StringBuilder _sql = new StringBuilder();

	/**
	 * 解析出 in 类型的sql
	 */
	private void addVar2sql() {
		_sql.append('(');
		char c = ' ';
		int l = var2.length();
		for (int i = 0; i < l; i++) {
			c = var2.charAt(i);
			if (c == ' ') {
				continue;
			}
			if (c == ',') {
				_sql.append(",");
				continue;
			}
			_sql.append('\'').append(c).append('\'');
		}
		if (c == ',')
			_sql.deleteCharAt(l - 1);
		_sql.append(')');
	}

	public String getSqlOfContent(String dbalias) {
		_sql.setLength(0);
		if (symbol == null) {
			return null;
		}
		if (field == null || field.length() == 0)
			return null;

		_sql.append(dbalias).append(field);
		switch (symbol) {
		case In:
			_sql.append(" in ");
			addVar2sql();
			return _sql.toString();
		case Equal:
			_sql.append('=');
		break;
		case Unequal:
			_sql.append(" <> ");
		break;
		case GT:
			_sql.append(" > ");
		break;
		case LT:
			_sql.append(" < ");
		break;
		case GTOrEqual:
			_sql.append(" >= ");
		break;
		case LTOrEqual:
			_sql.append(" <= ");
		break;
		default:
			return null;
		}
		return _sql.append('\'').append(var).append('\'').toString();

	}

	/**
	 * 解析元素格式:[ 状态元素 符号 值 ] 例如:状态1=1 返回 : true 正常解析, false 解析异常
	 */
	public boolean analyzing() {
		if (_content == null)
			return true;
		int n = _content.length();
		// s= 0: 元素的名称读取中,1: 读取结束,2表示读取结束但是有 in符号
		int s = 0;
		iserror = false;
		for (int i = 0; i < n; i++) {
			char l1 = _content.charAt(i);
			if (l1 == ' ') { // 过滤所有空格
				continue;
			}
			// 保存键值,读取一个char
			if (s == 1) {
				var = l1;
				return true;
			}
			// 读取后续所有的值
			if (s == 2) {
				var2.append(l1);
				continue;
			}
			char l2;
			// 判断是否有逻辑运算符
			try {
				switch (l1) {
				case '<':
					l2 = _content.charAt(i + 1);
					s = 1;
					if (l2 == '>') {
						i++;
						symbol = SymbolType.Unequal;
					} else if (l2 == '=') {
						i++;
						symbol = SymbolType.LTOrEqual;
					} else {
						symbol = SymbolType.LT;
					}
				break;
				case '>':
					s = 1;
					l2 = _content.charAt(i + 1);
					if (l2 == '=') {
						i++;
						symbol = SymbolType.GTOrEqual;
					} else {
						symbol = SymbolType.GT;
					}
				break;
				case '!':
					s = 1;
					l2 = _content.charAt(i + 1);
					if (l2 == '=') {
						i++;
						symbol = SymbolType.Unequal;
					} else
						symbol = SymbolType.Unknown;
				break;
				case '@':
					s = 2;
					symbol = SymbolType.In;
					var2 = new StringBuilder();
				break;
				case '=':
					s = 1;
					symbol = SymbolType.Equal;
					l2 = _content.charAt(i + 1);
					if (l2 == '=') {
						i++;
					}
				break;
				default:
					field.append(l1);
				}
			} catch (Exception e) {
				symbol = null;
				field = null;
				var = '2';
				var2 = null;
				_content = null;
				iserror = true;
				return false;
			}
		}
		return true;
	}

	/**
	 * 添加字符到表达式
	 */
	public void addChar(char c) {
		if (_content == null)
			_content = new StringBuilder();
		_content.append(c);
	}

	/**
	 * 获取表达式
	 */
	public String getContent() {
		if (_content == null)
			return null;
		return _content.toString();
	}

	/**
	 * 清空表达式
	 */
	public void clearContent() {
		_content = null;
	}

	public boolean isEmpty() {
		return childs.isEmpty();
	}

	/**
	 * 获取父节点
	 */
	public DependNode getParent() {
		return _parent;
	}
}